/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */
#pragma once

#include <noise/hard/Hardware.h>
#include <threads/Thread.h>
#include <threads/Lock.h>
#include <math/Vector3.h>
#include "Channel.h"
#ifdef MAC_VERSION
#include <openal/alc.h>
//#include <openal/alut.h>
#else
#include <alc.h>
#endif

namespace liba {
namespace noise {
namespace hard {
namespace openal {

class Hardware : public hard::Hardware
{
	ALCdevice * device;
	ALCcontext * context;
public:
	Hardware();
	virtual ~Hardware();
	virtual hard::Channel * create_static_channel( const Atom & channel_type, const filesystem::String & name);
	virtual hard::Channel * create_streaming_channel( const Atom & channel_type );
	virtual std::string get_name()const
	{
		return std::string("openal");
	}

	void life_cycle( double delta_time );

	void play_static_3d_channel(ChannelStatic * channel)
	{
		playing_channels.push_back(channel);
	}
	void stop_static_3d_channel(ChannelStatic * channel)
	{
		playing_channels.remove(channel);
	}
	void add_static_channel(ChannelStatic * channel)
	{
		static_channels.push_back(channel);
	}
	void remove_static_channel(ChannelStatic * channel)
	{
		static_channels.remove(channel);
	}
	void add_streaming_channel(ChannelStreaming * channel)
	{
		streaming_channels.push_back(channel);
	}
	void remove_streaming_channel(ChannelStreaming * channel)
	{
		streaming_channels.remove(channel);
	}
	
#ifdef IPHONE_VERSION
	void app_goes_background();
	void app_goes_active();
#endif
private:
	void ListenerPositionChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerPosition;
	void ListenerSpeedChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerSpeed;

	void ListenerFrontChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerFront;
	void ListenerUpChanged(const math::Vector3<float>& value);
	properties::DependencyProperty<math::Vector3<float> > listenerUp;

	void ExactVolumeChanged(double value);
	properties::DependencyProperty<double> exactVolume;

	typedef std::list<ChannelStatic *> ChannelStaticList;
	ChannelStaticList playing_channels;
	ChannelStaticList static_channels;
	typedef std::list<ChannelStreaming *> ChannelStreamingList;
	ChannelStreamingList streaming_channels;
	int max_playing_channels;

};

} // namespace openal
} // namespace hard
} // namespace noise
} // namesapce liba
using namespace liba;

